﻿using System;
using System.Collections.Generic;
using EnvDTE;
using EnvDTE80;


namespace VsTortoiseSVN.Commands
{
    /// <summary>
    /// SolutionExplorerSelectedItemsBase represents the base class for all VsTortoise commands
    /// that deal with selected items in the Solution Explorer.
    /// </summary>
    public abstract class SolutionExplorerSelectedItemsBase : CommandBase
    {
        public SolutionExplorerSelectedItemsBase(DTE2 app, string id)
            : base(app, id)
        {
        }

        /// <summary>
        /// Gets whether one physical file is selected.
        /// This indicates commands should perform context sensitive status queries.
        /// If more than one file is selected, only insenstive status queries are performed due to performance reasons.
        /// </summary>
        private bool IsPhysicalFileSelected
        {
            get
            {
                if (Application.SelectedItems.Count == 1)
                {
                    SelectedItem item = Application.SelectedItems.Item(1);
                    if (item.ProjectItem != null)
                    {
                        if (string.Compare(item.ProjectItem.Kind, Constants.vsProjectItemKindPhysicalFile, true) == 0)
                        {
                            return true;
                        }
                    }
                }

                return false;
            }
        }

        /// <summary>
        /// Gets a list with all filenames included in the current selection.
        /// </summary>
        protected List<string> GetFullNames()
        {
            List<string> fullNames = new List<string>(1 + Application.SelectedItems.Count);

            foreach (EnvDTE.SelectedItem item in Application.SelectedItems)
            {
                if (item.ProjectItem != null)
                {
                    item.ProjectItem.GetLongFullNames(fullNames);
                }
                else if (item.Project != null)
                {
                    item.Project.GetDirectoryNames(fullNames);
                }
                else
                {
                    // Not a ProjectItem nor a Project, must be the Solution
                    Application.Solution.GetDirectoryNames(fullNames);
                }
            }

            PathHelper.RemoveSubDirectories(fullNames);
            return fullNames;
        }

        /// <summary>
        /// Derived classes should not override this method, they should implement
        /// their query status logic in QueryContextSensitiveStatus() and QueryContextInsensitiveStatus() instead.
        /// </summary>
        public override vsCommandStatus QueryStatus()
        {
            if (Application.SelectedItems.Count > 0)
            {
                if (IsPhysicalFileSelected)
                    return QueryContextSensitiveStatus();
                
                return QueryContextInsensitiveStatus();
            }

            return vsCommandStatus.vsCommandStatusUnsupported;
        }

        /// <summary>
        /// Gets the context sensitive command status. This is only performed when exactly
        /// one physical file is selected. Derived classes override this method to implement
        /// their logic. Usually this method performs vairous svn commands for the file in question,
        /// so we don't want this to happen for multiple files for performance reasons.
        /// </summary>
        protected virtual vsCommandStatus QueryContextSensitiveStatus()
        {
            return vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
        }

        /// <summary>
        /// Gets the context insensitive command statsu. This is when more than one item has been selected.
        /// </summary>
        protected virtual vsCommandStatus QueryContextInsensitiveStatus()
        {
            return vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
        }
    }
}
